#include "App_Pool.h"

static char *mq_name = "/app_pool_mq"; // 队列文件的路径， /代表队列文件所在的目录 /dev/mqueue
static mqd_t mq;                       // 定义消息队列标识符
static int thread_count = 0;           // 定义线程数量
static pthread_t *thread_pool;         // 定义线程池

void *thread_recv(void *arg)
{
    Task task;
    while (1)
    {
        pthread_testcancel();
        // 1.接收任务
        if (mq_receive(mq, (char *)&task, sizeof(Task), NULL) == -1) {
            continue;
        }
        // 2.执行任务
        task.task_fun(task.arg);
        // 3.释放任务参数
        free(task.arg);
    }
}

int App_Pool_Init(int num)
{
    // 1.创建消息队列
    struct mq_attr attr;
    attr.mq_maxmsg = 5;             // 最大消息数量
    attr.mq_msgsize = sizeof(Task); // 最大消息大小
    mq = mq_open(mq_name, O_RDWR | O_CREAT, 0644, &attr);
    if (mq == -1)
    {
        printf("队列创建或打开失败\n");
        return -1;
    }

    // 2.创建进程
    thread_count = num;
    thread_pool = (pthread_t *)malloc(thread_count * sizeof(pthread_t));
    if (thread_pool == NULL)
    {
        printf("线程池内存分配失败\n");
        return -1;
    }
    for (int i = 0; i < thread_count; i++)
    {
        pthread_create(&thread_pool[i], NULL, thread_recv, NULL);
    }
}

void App_Pool_End(void)
{
    for (int i = 0; i < thread_count; i++)
    {
        // 1.取消线程
        pthread_cancel(thread_pool[i]);
        // 2.等待线程结束
        pthread_join(thread_pool[i], NULL);
    }
    // 3.释放内存
    free(thread_pool);
    // 4.关闭消息队列
    mq_close(mq);
    // 5.删除消息队列
    mq_unlink(mq_name);
}

void App_Pool_RegisterTask(int (*task_fun)(void *arg), void *arg)
{
    // 1.创建任务
    Task task;
    task.task_fun = task_fun;
    task.arg = arg;
    // 2.发送任务到消息队列
    mq_send(mq, (char *)&task, sizeof(Task), 0);
}
